定義
觀察者設計模式是一個非常受歡迎的行為型模式,它允許物件間建立一對多的依賴關係。當一個物件的狀態改變時,所有依賴於它的物件都會收到通知。
關鍵字
以下,我們將透過 Solid State Drive (SSD) 和 Driver 的例子,來解釋觀察者模式
1.1 Subject
class Observer;
class Subject {
public:
void addObserver(Observer* obs) {
observers.push_back(obs);
}
void removeObserver(Observer* obs) {
observers.erase(std::remove(observers.begin(), observers.end(), obs), observers.end());
}
protected:
void notify() {
for (Observer* obs : observers) {
obs->update();
}
}
private:
vector<Observer*> observers;
};
1.2 Observer
class Observer {
public:
virtual void update() = 0;
};
2.1 Concrete Subject
class SSD : public Subject {
public:
void receiveData(std::string data) {
this->data = data;
notify();
}
std::string getData() const {
return data;
}
private:
std::string data;
};
2.2 Concrete Observer
class KernelIODevice : public Observer {
public:
KernelIODevice(SSD* drive) : drive(drive) {}
void update() override {
std::cout << "Kernel I/O Device updated with data: " << drive->getData() << std::endl;
}
private:
SSD* drive;
};
class Driver : public Observer {
public:
Driver(SSD* drive) : drive(drive) {}
void update() override {
std::cout << "Driver processed the data: " << drive->getData() << std::endl;
}
private:
SSD* drive;
};
說明
int main() {
SSD mySSD;
KernelIODevice ioDevice(&mySSD);
Driver ssdDriver(&mySSD);
mySSD.addObserver(&ioDevice);
mySSD.addObserver(&ssdDriver);
mySSD.receiveData("Operating System Boot Sequence");
return 0;
}
Output
Kernel I/O Device updated with data: Operating System Boot Sequence
Driver processed the data: Operating System Boot Sequence
小結
註: GoF 書中提到的 Pub-Sub 與我們現代軟體開發使用的 Pub-Sub 還是有些不同,不可完全視作等號!
發布者 (Publisher):
訂閱者 (Subscriber):
回到我們的 SSD 和 Kernel I/O Device, Driver 的例子,SSD 可以被視為發布者,而 Kernel I/O Device 和 Driver 是訂閱者。當 SSD 接收到新數據或命令時(即狀態改變),它會通知所有的訂閱者,這些訂閱者隨後可以執行各自的操作,如更新緩存或處理數據
[1]. https://notfalse.net/11/pub-sub-pattern
[2]. https://www.agilecaterpillar.com/blog/observer/